home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / ch_4.3 / xah / ah_aoi.c next >
C/C++ Source or Header  |  1999-09-11  |  4KB  |  188 lines

  1. /* 
  2.  * ah_aoi.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /*
  10.  * AH_AOI
  11.  *
  12.  * domain Area Histogram for given Area Of Interest (in binary image)
  13.  * by flooding of domains and pixel counting
  14.  *
  15.  */
  16. #include "xah.h"
  17.  
  18. #define    F_TO_INT(x)    ( ((x)-(int)(x)<0.5) ? (int)(x) : (int)(x)+1 )
  19.  
  20. #define    ON        1
  21. #define    OFF        0
  22.  
  23. #define    SELECT_AOI    ON
  24. #define    CLR_BG        ON              /* clear screen, retain centroids */
  25.  
  26. #define    XDIM        512
  27. #define    YDIM        512
  28.  
  29.  
  30. #define    WHITE_ON_BLACK    0
  31. #define    BLACK_ON_WHITE    1
  32. #define    IMG_TYPE    BLACK_ON_WHITE
  33.  
  34. #define    BLACK        0
  35. #define    WHITE        255
  36. #define    OFF_WHITE    254
  37. #define    OFF_BLACK    1
  38.  
  39. #define    MIN_AREA    5              /* do not mark doms wt a < MIN_AREA */
  40.  
  41.  
  42. #undef    AOI_DEBUG
  43. #undef    DA_DEBUG
  44. #undef    S_DEBUG
  45.  
  46.  
  47. /* globals */
  48. int AREA_ONLY = 0;              /* when set, use routine proc_img() */
  49.  
  50.  
  51. /*
  52.  * scan domains, measure areas and construct centroids
  53.  */
  54. int
  55. ah_AOI (int x1, int y1, int x2, int y2, Image * imgIn, Image * imgOut, struct bubble *cbub, int nmax)
  56. {
  57.  
  58.   int i, j;
  59.  
  60.   int imin, jmin, imax, jmax;
  61.   int left_x, right_x;
  62.   int ncols, nrows;
  63.  
  64.   int id, nd;
  65.  
  66.   int interior_index, cur_index, new_index;
  67.   int flood_reg_index, mark_index = -1;
  68.  
  69.   unsigned int cur_area;
  70.   double xc, yc;
  71.  
  72.  
  73.   jmin = x1;
  74.   imin = y1;
  75.   jmax = x2;
  76.   imax = y2;
  77.  
  78.   left_x = jmin;
  79.   right_x = jmax - 1;
  80.   ncols = jmax - jmin;
  81.   nrows = imax - imin;
  82.  
  83.  
  84.  
  85. #ifdef AOI_DEBUG
  86.   printf ("\ndimensions of AOI to be scanned in bdy_AOI:\n");
  87.   printf ("...jmin = %d, imin = %d\n", jmin, imin);
  88.   printf ("...jmax = %d, imax = %d\n", jmax, imax);
  89.   printf ("\nrow limits:\n");
  90.   printf ("...left_x = %d, right_x = %d\n", left_x, right_x);
  91.   printf ("...number of cols: %d, number of rows: %d\n", ncols, nrows);
  92. #endif
  93.  
  94.  
  95.   new_index = GRAY;
  96.   if (IMG_TYPE == WHITE_ON_BLACK) {
  97.     interior_index = WHITE;
  98.     flood_reg_index = WHITE;
  99.     mark_index = OFF_WHITE;
  100.     /*
  101.      * Draw a border around image to eliminate
  102.      * edge effects for line fills
  103.      */
  104.     draw_rect (0, 0, imgIn->width - 1, imgIn->height - 1, imgIn, BLACK);
  105.   }
  106.   if (IMG_TYPE == BLACK_ON_WHITE) {
  107.     interior_index = BLACK;
  108.     flood_reg_index = BLACK;
  109.     mark_index = OFF_BLACK;
  110.     /*
  111.      * Draw a border around image to eliminate
  112.      * edge effects for line fills
  113.      */
  114.     draw_rect (0, 0, imgIn->width - 1, imgIn->height - 1, imgIn, WHITE);
  115.   }
  116.  
  117.   id = 0;
  118.   for (i = imin; i < imax; i++) {
  119.     for (j = left_x; j < right_x; j++) {
  120.       if ((cur_index = getpixel (j, i, imgIn)) == interior_index) {
  121.         if (id < nmax) {
  122.           if (AREA_ONLY == ON)
  123.             //??(cbub+id)->area = proc_img(j, i);
  124.             (cbub + id)->area = 0;
  125.           else {
  126.             cur_area = rfill (j, i, new_index, &xc, &yc, IMG_TYPE, imgIn);
  127.  
  128.             if (cur_area > MIN_AREA) {
  129.               (cbub + id)->area = cur_area;
  130.               xc /= (double) (cbub + id)->area;
  131.               yc /= (double) (cbub + id)->area;
  132.               mark_centroid (xc - x1, yc - y1, WHITE, flood_reg_index, imgOut);
  133.  
  134.               (cbub + id)->ctr.x = F_TO_INT (xc);
  135.               (cbub + id)->ctr.y = F_TO_INT (yc);
  136.               id++;
  137.             }
  138.           }
  139.         }
  140.         else {
  141.           printf ("\n...too many domains!! ");
  142.           printf (" ->check array dimension\n");
  143.           exit (1);
  144.         }
  145.       }
  146.     }
  147.   }
  148.   nd = id;
  149.  
  150.  
  151. #ifdef DA_DEBUG
  152.   printf ("...domain areas:\n");
  153.   for (id = 0; id < nd; id++) {
  154.     printf ("  %6u", (cbub + id)->area);
  155.     if ((id + 1) % 8 == 0)
  156.       printf ("\n");
  157.   }
  158.   printf ("\n");
  159. #endif
  160.  
  161.   return (nd);
  162. }
  163.  
  164. /*
  165.  * encode bubble areas depending on their size relative to the mean
  166.  */
  167. void
  168. encode_ba (double mean_a, double rmsq_a, struct bubble *b, int nd, Image * ip, int value)
  169. {
  170.   int id;
  171.   int x, y;
  172.   int radius = 3;
  173.  
  174.  
  175.  
  176.   for (id = 0; id < nd; id++) {
  177.     x = (b + id)->ctr.x;
  178.     y = (b + id)->ctr.y;
  179.  
  180.     if ((b + id)->area >= mean_a + 0.5 * rmsq_a)
  181.       draw_up_triang (x, y, 6, ip, value);
  182.     else if ((b + id)->area < mean_a - 0.5 * rmsq_a)
  183.       draw_dn_triang (x, y, 6, ip, value);
  184.     else
  185.       draw_circle ((int) x, (int) y, (int) radius, ip, value);
  186.   }
  187. }
  188.